classdef KNearestNeighbor ...
        < MultiClassClassifier ...
        & Modelable
    %KNEARESTNEIGHBOR K Nearest Neighbor
    %   Detailed explanation goes here
    
    properties ( SetAccess = protected )
        nK = 1
        distanceMetric = 'euclidean'
        classificationRule = 'nearest'
    end
    
    methods % Set methods
        function [  ] = setNK( this, nK )
            if nargin == 1
                this.nK = 1;
            end
            if nargin == 2
                this.nK = nK;
            end
        end
        
        function [  ] = setDistanceMetric( this, distanceMetric )
            if nargin == 1
                this.distanceMetric = 'euclidean';
            end
            if nargin == 2
                this.distanceMetric = distanceMetric;
            end
        end
        
        function [  ] = setClassificationRule( this, classificationRule )
            if nargin == 1
                this.classificationRule = 'nearest';
            end
            if nargin == 2
                this.classificationRule = classificationRule;
            end
        end
    end
    
    methods
        function [ this ] = KNearestNeighbor( name, nK, distanceMetric, classificationRule )
            if nargin == 0
                this.setName('knn');
            end
            if nargin >= 1
                this.setName(name);
            end
            if nargin >= 2
                this.setNK(nK);
            end
            if nargin >=3
                this.setDistanceMetric(distanceMetric);
            end
            if nargin >= 4
                this.setClassificationRule(classificationRule);
            end
        end
    end
    
    methods
        function [  ] = build( this, X1, Y1 )
            %BUILD Summary of this function goes here
            %   Detailed explanation goes here
            % KNearestNeighbor::
            
            this.model.X1 = X1;
            this.model.Y1 = Y1;
        end
        
        function [ result ] = apply( this, X2, Y2 )
            %APPLY Summary of this function goes here
            %   Detailed explanation goes here
            % KNearestNeighbor::
            
            result.Y_hat = str2num( ...
                knnclassify(X2, this.model.X1, num2str(this.model.Y1)));
            result.Y_out = result.Y_hat;
        end
    end
    
end

